import java.awt.*;
import javax.swing.*;
import java.awt.print.*;

 /*
  * Name: Printing.java
  * Function: Sets a component to be printed, creates a print job, and sends it to a printer.
  * 
  */

public class Printing implements Printable {
  private Component componentToBePrinted;
 
 /*
  * Name: printComponent(Component com)
  * Description: Starts the print.
  * Param: Component com
  * Returns: Nothing
  */
 
 public static void printComponent(Component com) {
    new Printing(com).print();
  }
  
   /*
  * Name: Printing
  * Description: Consturctor that sets the component to be printed 
  * Param: Component componentToBEPrinted
  * Returns: Nothing
  */
  
  public Printing(Component componentToBePrinted) {
    this.componentToBePrinted = componentToBePrinted;
  }
  
   /*
  * Name: print()
  * Description: Creates a print job and sends it to the printer.
  * Param: None
  * Returns: Nothing
  */
  
  public void print() {
    PrinterJob printJob = PrinterJob.getPrinterJob();
    printJob.setPrintable(this);
    if (printJob.printDialog())
      try {
        printJob.print();
      } catch(PrinterException pe) {
        System.out.println("Error printing: " + pe);
      }
  }
 /*
  * Name: int print(Graphics g, PageFormat pageFormat, int pageIndex)
  * Description: Inehierited abstract method from Printable
  * Param: Graphics g, PageFormat pageGormat, int pageIndex)
  * Returns: NO_SUCH_PAGE when more than 1 page
           : PAGE_EXISTS for first page
  */
  
  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    if (pageIndex > 0) {
      return(NO_SUCH_PAGE);
    } else {
      Graphics2D g2 = (Graphics2D)g;
      g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
      disableDoubleBuffering(componentToBePrinted);
      componentToBePrinted.paint(g2);
      enableDoubleBuffering(componentToBePrinted);
      return(PAGE_EXISTS);
    }
  }
 
    /*
  * Name: disableDoubleBuffering(Component com)
  * Description: Disables double buffering of component which can affect print quality
  * Param: Component com
  * Returns: Nothing
  */
  public static void disableDoubleBuffering(Component com) {
    RepaintManager currentManager = RepaintManager.currentManager(com);
    currentManager.setDoubleBufferingEnabled(false);
  }
 
    /*
  * Name: enableDoubleBuffering(Component com) 
  * Description: Enables double buffering once print job is done.
  * Param: Component com
  * Returns: Nothing
  */
  public static void enableDoubleBuffering(Component com) {
    RepaintManager currentManager = RepaintManager.currentManager(com);
    currentManager.setDoubleBufferingEnabled(true);
  }
}